import { ExecutionContext, Injectable, NotFoundException, UnauthorizedException } from '@nestjs/common'
import { Reflector } from '@nestjs/core'
import { AuthGuard } from '@nestjs/passport'
import { ExtractJwt } from 'passport-jwt'
import { Observable } from 'rxjs'
import { AuthStrategy } from '@/constants/auth.constant'
import { IS_PUBLIC_KEY } from '@/constants/auth.constant'
import { ResultData } from '@/utils/result'
import { ErrorEnum } from '@/constants/error-code.constant'

@Injectable()
export class JwtAuthGuard extends AuthGuard(AuthStrategy.JWT) {
	// private globalWhiteList = []
	private jwtFromRequestFn = ExtractJwt.fromAuthHeaderAsBearerToken('authorization')
	constructor(private reflector: Reflector) {
		super()
		// this.globalWhiteList = [].concat(this.config.get('perm.router.whitelist') || [])
	}
	// 校验 token
	canActivate(ctx: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
		// 是否是公共路由
		const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [ctx.getHandler(), ctx.getClass()])
		if (isPublic) return true
		return super.canActivate(ctx)
	}
	/**
	 * @description: 验完成后调用</boolean>/
	 * @param {*} error 这是 Passport 策略执行过程中发生的任何潜在错误。如果在验证过程中没有错误发生，这个值通常是 null
	 * @param {*} user 这是 Passport 策略验证成功后返回的用户对象。如果验证失败，这个值可能是 false 或 null，具体取决于你使用的 Passport 策略
	 * @param {*} info 如果验证失败，info通常是一个error对象
	 */
	handleRequest(error, user, info) {
		if (info || error) return ResultData.error(ErrorEnum.Token_Verification_Failed)
		if (!user) return ResultData.error(ErrorEnum.USER_NOT_FOUND)
		return user
	}
}
